package com.longtop.framework.security;

import com.longtop.framework.common.Message;

import java.util.ArrayList;
import java.util.List;

/**
 * 系统级异常（开发人员误操作或系统本身产生的异常，如数据库连接失败，空指针错误）的基类，是一个不受控异常基类。 可不用捕捉或传throws方式传递下去。 <p/> * 示例如下：<br>
 * 
 * <pre>
 * 1)抛出错误(Service)
 * public void getConnection() throws BaseUncheckedException {
 *      ...
 *      throw new BaseUncheckedException(&quot;e_login_database_notconnect&quot;);
 *      ...
 *      throw new BaseUncheckedException(&quot;e_login_connect_failed&quot;,new Object[]{&quot;admin&quot;,&quot;1234&quot;});
 *      ...
 * }
 * 2)捕捉错误(Action)
 * &lt;p/&gt;
 * public login() {
 *      try {
 *           ...
 *      } catch(BaseUncheckedException ex) {
 *          //如果只抛出一种错误，可不加if 条件判断
 *           if (ex.getExceptionKey().equals(&quot;e_login_database_notconnect&quot;)) {
 *               ...
 *               this.hintErrorMessage(ex.getMessage());
 *           }
 * &lt;p/&gt;
 *           if (ex.getExceptionKey().equals(&quot;e_login_connect_failed&quot;)) {
 *               ...
 *               this.hintErrorMessage(ex.getMessage());
 *           }
 *      }
 * }
 * </pre>
 * 
 * @author IntelliWeb Team
 * @version 2.0
 */
public class BaseUncheckedException extends RuntimeException {

	/**
	 * 错误Key，用于唯一标识错误类型。 exceptionKey必须在common/applicationMessage.properties中定义。
	 */
	private String exceptionKey = null;

	/**
	 * 传递给变量的错误值
	 */
	private Object[] exceptionValues = null;

	/**
	 * 根据Key从资源文件转成明文的错误信息
	 */
	private String message = null;

	public BaseUncheckedException() {
		super();
	}

	public BaseUncheckedException(String msg) {
		super();
		message = msg;
	}

	public BaseUncheckedException(String key, Throwable rootCause) {
		super(rootCause);
		this.exceptionKey = key;
		this.exceptionValues = null;
		// 转成明文错误信息
		message = Message.getMessage(key);
		if (message.equals("")) {
			message = key;
		}
	}

	public BaseUncheckedException(String key, String message) {
		super();
		this.exceptionKey = key;
		this.message = message;
	}

	public BaseUncheckedException(String key, Object[] args) {
		super();
		this.exceptionKey = key;
		this.exceptionValues = args;
		// 转成明文错误信息
		this.message = Message.getMessage(key, args);
	}

	public BaseUncheckedException(Throwable rootCause, String key, Object[] args) {
		super(rootCause);
		this.exceptionKey = key;
		this.exceptionValues = args;
		// 转成明文错误信息
		this.message = Message.getMessage(key, args);
	}

	public Object[] getExceptionValues() {
		return exceptionValues;
	}

	public String getExceptionKey() {
		return exceptionKey;
	}

	/**
	 * 取得转成明文的错误信息
	 * 
	 * @return String 返回转成明文的错误信息
	 */
	public String getMessage() {
		return message == null || message.trim().equals("") ? super.getMessage() : message;
	}

	public String getMessagesString() {
		String[] msgs = this.getMessages();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < msgs.length; i++) {
			sb.append(msgs[i] + "\n");
		}
		return sb.toString();
	}

	public String[] getMessages() {
		Throwable[] throwables = this.getThrowables();
		String[] msgs = new String[throwables.length];
		for (int i = 0; i < throwables.length; i++) {
			msgs[i] = throwables[i].getMessage();
		}
		return msgs;
	}

	public Throwable[] getThrowables() {
		List list = new ArrayList();
		Throwable throwable = this;
		while (throwable != null) {
			list.add(throwable);
			throwable = throwable.getCause();
		}
		return (Throwable[]) list.toArray(new Throwable[list.size()]);
	}
}
